【入門記事】2020年時点のBigQuery MLまとめ
こんにちは、Mr.Moです。
このエントリは『クラスメソッド BigQuery Advent Calendar 2020』22本目のエントリです。12/25のアドベントカレンダー終了まで、弊社クラスメソッド データアナリティクス事業本部のメンバーで Google BigQuery に関する記事を紡いでいこうと思います。
- クラスメソッド BigQuery Advent Calendar 2020 の記事一覧 | Developers.IO
- クラスメソッド BigQuery Advent Calendar 2020 - Qiita
当エントリでは現時点(2020年12月)でのBigQuery MLについてまとめてみたいと思います。
BigQuery MLとは
BigQuery ML を使用すると、BigQuery で標準 SQL クエリを使用して、機械学習モデルを作成し実行できます。BigQuery ML では、既存の SQL ツールやスキルを活用できるので、誰でも簡単に機械学習を利用できます。BigQuery ML では、データを移動する必要がないため、開発スピードを向上させることができます。
BigQuery ML(以下、BQML)には下記の特徴があります。
- SQLさえ分かれば専門的な知識が無くても機械学習を使うことができる
- DWH上で機械学習できるので、BigQueryからデータを移動させる処理も不要
- 入力値の変換や補完をしてくれる(標準化やワンホットエンコーディング、欠損値の補完)
BigQuery(DWH)上で機械学習モデルの作成ができるということで、データの移動といった事前の工程を省略することができます。何回か試行するとなった時にも効率が良さそうです。また、BigQuery ML(以下、BQML)では機械学習モデルの作成までも普段使い慣れているSQLで実施できてしまうので学習コストを抑えることもできますね。機械学習とデータウェアハウス(DWH)の分野に強いGCPならではのこの機能、もう少し詳細に見ていきましょう。
サポートされているモデルと機械学習の手法
実行できる機械学習の手法は回帰
、分類
、クラスタリング
、レコメンデーション
、時系列予測
であり、それぞれ下記のモデルがサポートされています。
- 回帰
- Linear regression(線形回帰)
- Deep Neural Network(DNN、回帰)
- XGBoost(回帰)
- AutoML Tables(回帰)
- 分類
- Binary logistic regression(2項分類)
- Multiclass logistic regression(多項分類)
- Deep Neural Network(DNN、分類)
- XGBoost(分類)
- AutoML Tables(分類)
- クラスタリング
- K-means clustering(K 平均法クラスタリング)
- レコメンデーション
- Matrix Factorization
- 時系列予測
- Time series(ARIMA)
さらに上記のモデル以外を扱いたい場合も外部から TensorFlow モデルをインポートできる機能、TensorFlow model importing
もサポートされていますね。
なお、上記のうちDNN,XGBoostやAutoMLは別のサービスを使うイメージのようで、それぞれDNN,XGBoost:AI Platformサービス
、AutoML:AutoML Tablesサービス
でトレーニングされるようです。(DNN,XGBoostやAutoMLは組み込み以外のモデルという扱いになります)
料金体系
料金体系については定額とオンデマンド(クエリ実行の都度処理したバイト数などで課金)があり、組み込みモデルと組み込み以外のモデル(DNN,XGBoostやAutoML以外)でも料金のかかり方が違ってきます。
下記は東京リージョンでオンデマンドでトレーニングを実施した時の料金です。
- 組み込みモデル
- $300.00 per TB
- 組み込みモデル以外
- $6.00 per TB + AI Platformでの料金
あとは評価(Evaluation)、検査(Inspection)、予測(Prediction)といったタスク時にも$6.00 per TB
の料金がかかります。
BQMLの基本構文
BQMLで主に行うタスクは下記の3つです。
- モデルのトレーニング
- モデルの評価
- 予測
機械学習のタスクですが、もちろん上記すべてSQLで実施できます。公式のチュートリアルを題材に見ていきましょう。
と、その前に下記のようにBigQuery web UIにアクセスし事前にデータセットの作成をしておきます。
モデルのトレーニング
CREATE MODEL ステートメントを使ってモデルのトレーニングを行います。SQLに慣れている方ならあまり違和感が無いのではないでしょうか。ポイントはOPTIONS
の部分ですね。ここで使用するモデルのタイプ(model_type)や目的変数である列名(input_label_cols)、各モデルのタイプで指定できるパラメータなどを設定します。詳細は公式ドキュメントを参照ください。
CREATE MODEL `blog.natality_model` OPTIONS (model_type='linear_reg', input_label_cols=['weight_pounds']) AS SELECT weight_pounds, is_male, gestation_weeks, ML.QUANTILE_BUCKETIZE(mother_age, 5) OVER() AS bucketized_mother_age, CAST(mother_race AS string) AS mother_race, ML.FEATURE_CROSS(STRUCT(is_male, CAST(mother_race AS STRING) AS mother_race)) is_male_mother_race FROM `bigquery-public-data.samples.natality` WHERE weight_pounds IS NOT NULL AND RAND() < 0.001
なお、BQMLにはTRANSFORM
という機能が用意されており、これは下記のSQLを見ておわかりいただけると思いますが前処理の設定をするものです。TRANSFORM
を使うと何が嬉しいかと言うと予測の時に前処理で指定した(TRANSFORM句で設定している)長い構文を指定する必要が無くなるという点です。詳しくは予測のところで見ていただこうと思います。
CREATE MODEL `blog.natality_model` TRANSFORM(weight_pounds, is_male, gestation_weeks, ML.QUANTILE_BUCKETIZE(mother_age, 5) OVER() AS bucketized_mother_age, CAST(mother_race AS string) AS mother_race, ML.FEATURE_CROSS(STRUCT(is_male, CAST(mother_race AS STRING) AS mother_race)) is_male_mother_race) OPTIONS (model_type='linear_reg', input_label_cols=['weight_pounds']) AS SELECT * FROM `bigquery-public-data.samples.natality` WHERE weight_pounds IS NOT NULL AND RAND() < 0.001
BQMLのWeb UI上では下記のような感じです。
モデルの評価
トレーニングが終わったら出来上がったモデルがどのような状態か評価をしていきます。BQMLでは評価関数(ML.EVALUATE
)が用意されているのでそれを使うだけでモデルの状態(精度など)を把握することができます。なお、評価関数には他にもML.ROC_CURVE
(ロジスティック回帰かつ2項分類でしか使えない)やML.CONFUSION_MATRIX
(ロジスティック回帰でしか使えない)も用意されています。
SELECT * FROM ML.EVALUATE(MODEL `blog.natality_model`, ( SELECT * FROM `bigquery-public-data.samples.natality` WHERE weight_pounds IS NOT NULL))
予測
トレーニングして評価関数でモデルの状態を確かめてを繰り返して納得するモデルが出来上がったらいよいよ予測ができる段階です。BQMLでは予測関数(ML.PREDICT
)が用意されているのでまたもやこれを使うだけで簡単にモデルに予測のタスクを実行させることができます。ただし注意点としては、トレーニング時に渡していたデータと同じ状態のデータをモデルに入力する必要があるため、下記のように前処理を施したSQLを再び使うことになります。ちょっと面倒ですね...そこでTRANSFORM
の出番です。
SELECT predicted_weight_pounds FROM ML.PREDICT(MODEL `blog.natality_model`, ( SELECT weight_pounds, is_male, gestation_weeks, ML.QUANTILE_BUCKETIZE(mother_age, 5) OVER() AS bucketized_mother_age, CAST(mother_race AS string) AS mother_race, ML.FEATURE_CROSS(STRUCT(is_male, CAST(mother_race AS STRING) AS mother_race)) is_male_mother_race FROM `bigquery-public-data.samples.natality` WHERE state = "WY"))
TRANSFORM
を使うとトレーニング時に指定した前処理を覚えてくれているので、下記のようにシンプルなSQL文でモデルに予測を実行させることができます。(上記のSQLと下記のSQLは内容的には同じことを実施しています。)
SELECT predicted_weight_pounds FROM ML.PREDICT(MODEL `blog.natality_model`, ( SELECT * FROM `bigquery-public-data.samples.natality` WHERE state = "WY"))
ちなみに、予測を実行する時に使う予測関数は使用したモデルのタイプで若干異なる関数を使うことになるので気にしておきましょう。具体的には時系列モデルを選択してトレーニングした場合はML.FORECAST
、レコメンデーションのモデルを選択してトレーニングした場合はML.RECOMMEND
の予測関数を使用することになります。
その他
他にもモデルの状態を確かめることができる検査関数がいくつか用意されていますので、適宜使用して作成されたモデルの内容を把握すると良いでしょう。
下記は特徴量の重要度を確認するML.WEIGHTS
を使っているところです。(各特徴量が予測結果に与える影響度を確認することができます)
まとめ
GCPのサービスの中でも中心的なサービスであるBigQuery、そしてその機能の1つであるBQML。年々アップデートも入っていて今後もさらなる期待感があります。SQLの世界で機械学習が使えるというのも機械学習の民主化がぐっと加速しそうですね。個人的にもSQL好きなので使っていてものすごく楽です(笑)。新たに追加されたAutoML Tablesも大変強力ですし、今後のさらなる機能強化が待ち遠しいサービスです。